package com.dengtacj.puppeteerspider.actions;

import cn.hutool.crypto.SecureUtil;
import com.dengtacj.puppeteerspider.config.PuppeteerConfig;
import com.dengtacj.puppeteerspider.enties.SpAnnouncementInfoLettersBean;
import com.dengtacj.puppeteerspider.enties.StockStopBean;
import com.dengtacj.puppeteerspider.utils.DateUtils;
import com.dengtacj.puppeteerspider.utils.JDBCTemplateUtil;
import com.dengtacj.puppeteerspider.utils.SQLMergeParamsUtils;

import com.ruiyun.jvppeteer.core.browser.Browser;
import com.ruiyun.jvppeteer.core.page.ElementHandle;
import com.ruiyun.jvppeteer.core.page.Page;
import com.ruiyun.jvppeteer.core.page.Response;
import com.ruiyun.jvppeteer.options.PageNavigateOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class StockShNoticeAction {

    private JdbcTemplate jdbcTemplate;


    private Browser browser = null;
    private Page page = null;
    private PageNavigateOptions pageNavigateOptions;
    private String latestStartDate = null;
    private String currentDate = null;
    private String pageNav = "http://www.sse.com.cn/home/search/?inputval=1&webswd=停牌&stm=";

    private Browser browser1;
    private Page page1;


    public StockShNoticeAction(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;

        latestStartDate = DateUtils.getPastDate(30, null);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd");
        String start = DateUtils.getPastDate(30, simpleDateFormat);
        String end = simpleDateFormat.format(new Date());
        pageNav = pageNav + "" + start + "&etm=" + end + "&pCode=8319&temp=1&cCode=8319";
    }


    public void init() {
        try {
            if (browser == null && page == null) {
                browser = new PuppeteerConfig().initBrowser();
                page = browser.newPage();
                //设置参数防止检测
                page.evaluateOnNewDocument("() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => undefined } }) }");
                page.evaluateOnNewDocument("() =>{ window.navigator.chrome = { runtime: {},  }; }");
                page.evaluateOnNewDocument("() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }");
                page.evaluateOnNewDocument("() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }");

                pageNavigateOptions = new PageNavigateOptions();
                pageNavigateOptions.setTimeout(80 * 1000);
                List<String> waitUtil = new ArrayList<>();
                waitUtil.add("domcontentloaded");
                pageNavigateOptions.setWaitUntil(waitUtil);
            }

            pageSearch(page, pageNavigateOptions);
            page.waitFor("5000");

            String maxPageNum = "0";

            page.waitFor("#pageGro");
            maxPageNum = (String) page.$eval("#pageGro ul#pageinfo", "function(e){ var list = e.innerText.split('\\n'); list = list.filter(val=>{if(!isNaN(val)){return val}});return list.pop() }");

            log.info("当前页面共有: " + maxPageNum + "页数据");

            int maxPage_int = Integer.parseInt(maxPageNum);
            Integer currentPageNum = 1;

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

            for (int i = 0; i < maxPage_int; i++) {

                if (latestStartDate != null && currentDate != null && DateUtils.compare_date(latestStartDate, currentDate, simpleDateFormat) > 0) {
                    page.close();
                    browser.close();
                    return;
                }
                getTableData(browser, page, currentPageNum, maxPage_int);
                page.evaluate("function(){ let list=document.querySelector('#pageGro ul#pageinfo'); for(var i=0;i<list.length;i++){  if(list[i].tagName==='LI'&&list[i].children[0].getAttribute('class')=='nextPage'){  list[i].children[0].click(); break;}}  }", new ArrayList<>());
                currentPageNum++;
                page.waitFor("500");

            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.error("error: " + e.toString());
        }
    }

    /**
     * 初始化爬取的数据 所需要的初始化的查询条件
     */
    private void pageSearch(Page page, PageNavigateOptions pageNavigateOptions) {
        try {
            page.goTo(pageNav, pageNavigateOptions);
            page.waitFor("20000");
            page.waitFor(".sse_query_wrap  .sse_query_tool  .sse_con_query");
            page.waitFor("5000");

            page.click(".sse_query_wrap  .sse_query_tool  .sse_con_query");
            page.click(".ms-drop.ms-bottom ul  li:nth-child(2)");
            page.waitFor("3000");

        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            log.error("点击的元素不存在" + e.toString());
        }

    }

    private void getTableData(Browser browser, Page page, Integer pageNum, Integer maxPageNum) {
        log.info("当前爬取的是第" + pageNum + "页");
        List<ElementHandle> domList = null;
        try {
            page.waitFor("#sse_query_list");
            domList = page.$$("#sse_query_list>dl");
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.error("当前dom找不到 -> #sse_query_list>dl " + e.toString());
        }
        log.info("当前页共有" + domList.size() + "条数据");

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            for (int i = 0; i < domList.size(); i++) {

                String domNode = null;
                domNode = "#sse_query_list>dl:nth-child(" + (i + 1) + ")";

                currentDate = (String) page.$eval(domNode + ">dd>a>span", "(e)=> e.innerText");
                log.info(" latestStartDate: " + latestStartDate + " , currentDate : " + currentDate);
                if (latestStartDate != null && currentDate != null && DateUtils.compare_date(latestStartDate, currentDate, simpleDateFormat) > 0) {

                    page1.close();
                    browser1.close();
                    return;
                }

                String detailUrl = (String) page.$eval(domNode + ">dd>a", "(e)=> e.getAttribute('href')");
                detailUrl = "http://www.sse.com.cn" + detailUrl;

                log.info("detailUrl: " + detailUrl);

                getHtmlDomData(detailUrl);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (maxPageNum.equals(pageNum)) {
            browser.close();
        }
    }

    /**
     * @param url
     * @description 解析 html
     */
    private void getHtmlDomData(String url) {

        browser1 = new PuppeteerConfig().initBrowser();
        page1 = browser1.newPage();

        StockStopBean stockStopBean = new StockStopBean();
        try {
            page1.goTo(url, pageNavigateOptions);

            page1.waitFor("5000");
            page1.waitFor(".artcle_page .article-infor");
            String fragment = (String) page1.$eval(".artcle_page .article-infor", "function(e){ var shareDiv = document.querySelector('.artcle_page .article-infor  div.js_output_apphide'); var timeline = document.querySelector('.artcle_page .article-infor  div.article_opt');   var shareSpan = document.querySelector('.artcle_page .article-infor  span.js_output_apphide'); timeline.removeChild(shareSpan);    e.removeChild(shareDiv); return e.innerHTML }");

            String title = (String) page1.$eval(".artcle_page .article-infor  h2", "function(e){ return e.innerText }");
            fragment = fragment.replaceAll("\\n", "");
            fragment = fragment.replaceAll("\\t", "");
            fragment = fragment.replaceAll("\"", "\'");

            String fragmentText = (String) page1.$eval(".artcle_page .article-infor", "function(e){ return e.innerText }");

            fragmentText = fragmentText.replaceAll("\\n", "");
            fragmentText = fragmentText.replaceAll(" ", "");
            String fragmentTextlen = "" + fragmentText.length();

            String stockName = "";
            if (title.startsWith("关于")) {
                if (title.indexOf("）") > -1) {
                    stockName = title.substring(0, title.indexOf("（"));
                    stockName = stockName.replace("关于", "");
                } else {
                    stockName = title.substring(0, title.indexOf("公司"));
                    stockName = stockName.replace("关于", "");
                    stockName = stockName + "公司";
                }
            } else if (title.indexOf("关于") == -1) {
                stockName = title.substring(0, title.indexOf("临时停牌"));
            }
            stockName = stockName.trim();
            stockName = stockName.replaceAll("\"","");

            String str = "" + fragment;

            str = str.replaceAll(" ", "");
            String patten = "(\\d{6})";
            Pattern compile = Pattern.compile(patten);
            Matcher matcher = compile.matcher(str);

            String stockId = "";
            if (matcher.find() == true) {
                stockId = matcher.group(0);
            }
            String sta_time = (String) page1.$eval(".artcle_page .article-infor .article_opt i", "function(e){ return e.innerText }");
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String create_time = simpleDateFormat.format(date);


            String style = ".content p>h2{font-size: 28px;color: #050505;padding-bottom: 40px;font-weight: normal;line-height: 50px; margin-top: 0;padding-top: 20px;text-align: center;margin-bottom: 0;} " +
                    ".content p>.article_opt { padding: 0 0 20px 23px;overflow: hidden;font-weight: normal; margin-bottom: 20px;    border-bottom: 1px solid #e6e6e6; }" +
                    ".content p>.article_opt i {font-size: 16px;padding-left: 0;font-style: normal;line-height: 26px;display: inline-block;color: #8d8d8d;box-sizing: border-box;}" +
                    ".content p>p{    font-size: 16px;padding-left: 0;line-height: 160%;padding: 0 20px 15px;color: #4d4d4d;margin: 0 0 10px;}";


            stockStopBean.setReport_id(SecureUtil.md5(url));
            stockStopBean.setStk_code(stockId);
            stockStopBean.setTitle(title);
            stockStopBean.setTag_id("10090");
            stockStopBean.setTag_name("临时停牌");
            stockStopBean.setOnline_status("0");
            stockStopBean.setPublish_time(sta_time);
            stockStopBean.setData_status("0");
            stockStopBean.setCreate_time(create_time);
            stockStopBean.setS_code("SHA");
            stockStopBean.setCreater("上海交易所");
            stockStopBean.setUpdate_time(create_time);
            stockStopBean.setUpdater("admin");
            stockStopBean.setCompany(stockName);
            stockStopBean.setContent(fragment);
            stockStopBean.setContent_txt(fragmentText);
            stockStopBean.setContent_len(fragmentTextlen);
            stockStopBean.setStyle(style);
            stockStopBean.setUrl(url);

            log.info(stockStopBean.toString());
            insertData(stockStopBean);

            page1.close();
            browser1.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
            try {
                page1.close();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
            browser.close();
        }

    }

    private void insertData(StockStopBean stockStopBean) {

        String stockStopBean_params = null;
        try {
            stockStopBean_params = SQLMergeParamsUtils.getObjectValue(stockStopBean, "cms_notice_info_copy1");
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info(stockStopBean_params);

        Boolean aBoolean = hasOne(stockStopBean.getReport_id());
        if (!aBoolean) {
            jdbcTemplate.execute(stockStopBean_params);
        } else {
            log.info("已保存数据库");
        }

    }

    private Boolean hasOne(String reportId) {

        String sql = "SELECT *  from  cms_notice_info_copy1 WHERE report_id=" + "\"" + reportId + "\"";
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql);
        boolean next = sqlRowSet.next();
        return next;
    }
}
